﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RebEngine.Interfaces;
using RebEngine.Managers;

namespace RebEngine.GameComponents
{
    public class Camera
    {
        public Matrix View { get; set; }
        public Matrix World { get; set; }
        public Matrix Projection { get; set; }

        public Vector3 Position { get; set; }
        public Vector3 Reference { get; set; }

        public float NearPlane { get; set; }
        public float FarPlane { get; set; }

        public float ViewAngle { get; set; }

        public float _yaw { get; set; }
        public float _pitch { get; set; }

        /// <summary>
        /// Used to test the Objects against the cameras frustrum
        /// </summary>
        public BoundingFrustum Frustrum { get; private set; }

        public Camera()
        {
            View = Matrix.Identity;
            Projection = Matrix.Identity;
            _yaw = 0.0f;
            _pitch = 0.0f;
            ViewAngle = MathHelper.Pi / 3;

            Position = Vector3.Backward;
            Reference = Vector3.Zero;

            NearPlane = 0.1f;
            FarPlane = 5000.0f;
        }

        public virtual void RotateY(float angle)
        {
            angle = MathHelper.ToRadians(angle);
            if (_yaw >= MathHelper.Pi * 2)
                _yaw = MathHelper.ToRadians(0.0f);
            else if (_yaw <= -MathHelper.Pi * 2)
                _yaw = MathHelper.ToRadians(0.0f);
            _yaw += angle;
        }

        public virtual void RotateX(float angle)
        {
            angle = MathHelper.ToRadians(angle);
            _pitch += angle;
            if (_pitch >= MathHelper.ToRadians(75))
                _pitch = MathHelper.ToRadians(75);
            else if (_pitch <= MathHelper.ToRadians(-75))
                _pitch = MathHelper.ToRadians(-75);
        }


        public void Translate(Vector3 move)
        {
            Matrix forwardMovement = Matrix.CreateRotationY(_yaw);
            Vector3 v = new Vector3(0, 0, 0);
            v = Vector3.Transform(move, forwardMovement);

            Position += new Vector3(v.X, v.Y, v.Z);
        }

        public void Update()
        {
            Matrix rotationMatrix = Matrix.CreateRotationY(_yaw);
            Vector3 transformedReference = Vector3.Transform(Reference, rotationMatrix);
            transformedReference += Position;
            View = Matrix.CreateLookAt(Position, transformedReference, Vector3.Up);
            Frustrum = new BoundingFrustum(Matrix.Multiply(View, Projection));
            Projection = Matrix.CreatePerspectiveFieldOfView(ViewAngle, (EngineManager.Width / EngineManager.Height), NearPlane, FarPlane);
        }
       
    }
}
